package com.chenfan.mcn.event;

import com.chenfan.mcn.config.UserVoContextHolder;
import com.chenfan.mcn.extension.mybatisplus.BaseAssembler;
import lombok.Getter;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wulg
 * @date 2023/7/12
 */
@Getter
public class OperateLogBatchEvent<T extends BaseAssembler> {

    /**
     * 业务ID
     */
    private Long bussinessId;

    /**
     * 业务类型
     */
    private Integer bussinessType;

    /**
     * 操作类型
     */
    private Integer operationType;

    /**
     *  变更对象
     */
    private List<ImmutablePair<T, T>> valuePair;

    /**
     * 操作时间
     */
    private Date operationTime;

    /**
     * 操作人id
     */
    private Long operationBy;

    /**
     * 操作人名称
     */
    private String operationName;


    public OperateLogBatchEvent(final Long bussinessId, final Integer bussinessType, final Integer operationType, final List<ImmutablePair<T, T>> valuePair, final Date operationTime, final Long operationBy, final String operationName) {
        this.bussinessId = bussinessId;
        this.bussinessType = bussinessType;
        this.operationType = operationType;
        this.valuePair = valuePair;
        this.operationTime = operationTime;
        this.operationBy = operationBy;
        this.operationName = operationName;
    }

    /**
     * 构建方法
     * @param <T>
     * @return
     */
    public static <T extends BaseAssembler> OperateLogBatchEventBuilder<T> builder() {
        return new OperateLogBatchEventBuilder<T>();
    }

    /**
     * 操作日志构建者
     * @param <T>
     */
    public static class OperateLogBatchEventBuilder<T extends BaseAssembler> {
        private Long bussinessId;
        private Integer bussinessType;
        private Integer operationType;
        private List<ImmutablePair<T, T>> valuePair;

        public OperateLogBatchEventBuilder() {
            valuePair = new ArrayList<>(16);
        }

        public OperateLogBatchEventBuilder<T> bussinessId(final Long bussinessId) {
            this.bussinessId = bussinessId;
            return this;
        }

        public OperateLogBatchEventBuilder<T> bussinessType(final Integer bussinessType) {
            this.bussinessType = bussinessType;
            return this;
        }

        public OperateLogBatchEventBuilder<T> operationType(final Integer operationType) {
            this.operationType = operationType;
            return this;
        }

        public OperateLogBatchEventBuilder<T> compare(final T before, final T after) {
            valuePair.add(new ImmutablePair<>(before, after));
            return this;
        }

        public OperateLogBatchEvent<T> build() {
            return this.build(null, null);
        }

        public OperateLogBatchEvent<T> build(Long operationBy, String operationName) {
            return new OperateLogBatchEvent<T>(
                    this.bussinessId,
                    this.bussinessType,
                    this.operationType,
                    this.valuePair,
                    new Date(),
                    ObjectUtils.defaultIfNull(operationBy, UserVoContextHolder.getUserId()),
                    ObjectUtils.defaultIfNull(operationName, UserVoContextHolder.getUserName()));
        }
    }
}
